package com.haiyou.common.util;

import com.haiyou.common.constant.MessageCode;
import com.haiyou.common.exception.BusinessException;

import javax.validation.ConstraintViolation;
import javax.validation.Validation;
import javax.validation.Validator;
import java.util.List;
import java.util.Set;
import java.util.regex.Pattern;
import java.util.stream.Collectors;

/**
 * hibernate-validator校验工具类
 * <p>
 * 参考文档：http://docs.jboss.org/hibernate/validator/5.4/reference/en-US/html_single/
 *
 * @author huangzl
 */
public class ValidatorUtil {

    /**
     * 正则表达式:验证邮箱
     */
    private static final String REGEX_EMAIL = "^(\\w+([-.][A-Za-z0-9]+)*){3,18}@\\w+([-.][A-Za-z0-9]+)*\\.\\w+([-.][A-Za-z0-9]+)*$";

    /**
     * 正则表达式:验证手机
     */
    private static final String REGEX_PHONE = "^1[3-9]\\d{9}$";

    private static Validator validator;

    static {
        validator = Validation.buildDefaultValidatorFactory().getValidator();
    }

    /**
     * 校验对象
     *
     * @param object 待校验对象
     * @param groups 待校验的组
     * @throws BusinessException 校验不通过，则报BusinessException异常
     */
    public static void validateEntity(Object object, Class<?>... groups)
            throws BusinessException {
        Set<ConstraintViolation<Object>> constraintViolations = validator.validate(object, groups);
        if (!constraintViolations.isEmpty()) {
            for (ConstraintViolation<Object> constraint : constraintViolations) {
                throw new BusinessException(MessageCode.ERROR.getCode(), constraint.getMessage());
            }
        }
    }

    /**
     * 校验邮箱
     *
     * @param email
     * @return 校验通过返回true，否则返回false
     */
    public static boolean isEmail(String email) {
        return Pattern.matches(REGEX_EMAIL, email);
    }


    /**
     * 校验手机
     *
     * @param phone
     * @return 校验通过返回true，否则返回false
     */
    public static boolean isPhone(String phone) {
        return Pattern.matches(REGEX_PHONE, phone);
    }


    /**
     * 手动校验集合参数
     *
     * @param targets 被验证目标集合
     */
    public static void validatedTargetForList(List<?> targets) {
        String errorMessage = targets.stream().flatMap(target -> validator.validate(target).stream().
                map(ConstraintViolation::getMessage)).distinct().collect(Collectors.joining(" 、 "));
        if (!StringUtils.isEmpty(errorMessage)) {
            throw new BusinessException(errorMessage);
        }
    }
}
